/**
 * @Author       : Mo 2427995270@qq.com
 * @Date         : 2025-08-14 21:14:38
 * @LastEditTime : 2025-08-17 02:05:07
 * @FilePath     : \ZN-1000-BL\mobl\hal_driver\ll_crc.c
 * @Description  : crc低层驱动
 * @Version      : V1.0
 * @History      :
 * @Note         :
 */
/***************************************Includes***********************************/
#include "ll_crc.h"

#if defined(GD32F407)
#include "gd32f4xx.h"
#elif defined(STM32F40_41xxx)
#include "stm32f4xx.h"
#elif defined(GD32F10X_HD)
#include "gd32f10x.h"
#elif defined(STM32F10X_HD)
#include "stm32f10x.h"
#elif defined(PY32F071xB)
#include "py32f0xx.h"
#else
#error "No device selected"
#endif

/************************************Private Macros********************************/
// #define


/**********************************Private Statement*******************************/


/***********************************Public Variables*******************************/



/**********************************Private Variables*******************************/

#if defined(PY32F071xB)
static CRC_HandleTypeDef crc_handle = {
    .Instance = CRC,
};
#endif


/**********************************Public Functions********************************/

void crc_ll_init(void) {
// 硬件CRC时钟使能
#if defined(GD32F407) || defined(GD32F10X_HD)
    rcu_periph_clock_enable(RCU_CRC);
#elif defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
#elif defined(PY32F071xB)
    __HAL_RCC_CRC_CLK_ENABLE();
#endif
}

/**
 * @brief crc32校验
 * @param  crc              上次crc计算的结果 首次需保证crc传入0xffffffff 硬件crc是不使用该参数的
 * @param  check_data       要校验的数据地址
 * @param  num_of_data      校验数据的数量  字
 * @return uint32_t 校验结果
 * @note 可修改为硬件CRC32，需保证多项式为0x4C11DB7
 */
uint32_t crc_ll_crc32(uint32_t crc, uint32_t *check_data, uint32_t num_of_data) {
    /**********************调用硬件crc*******************/
#if defined(STM32F40_41xxx) || defined(GD32F10X_HD)
    crc = CRC_CalcBlockCRC(check_data, num_of_data);
#elif defined(GD32F407) || defined(STM32F10X_HD)
    crc = crc_block_data_calculate(check_data, num_of_data);
#elif defined(PY32F071xB)
    crc = HAL_CRC_Accumulate(&crc_handle, check_data, num_of_data);
#else
    const uint32_t dwPolynomial = 0x04c11db7; // STM32内置的多项式
    uint32_t xbit;
    uint32_t data;
    // uint32_t	CRC32 = 0xFFFFFFFF;
    uint32_t bits;
    uint32_t i;

    for (i = 0; i < num_of_data; i++) {
        xbit = 1U << 31;
        data = check_data[i];
        for (bits = 0; bits < 32; bits++) {
            if (crc & 0x80000000) {
                crc <<= 1;
                crc ^= dwPolynomial;
            } else
                crc <<= 1;

            if (data & xbit)
                crc ^= dwPolynomial;

            xbit >>= 1;
        }
    }

#endif
    return crc;
}
/**
 * @brief 复位CRC寄存器 使用硬件CRC时需实现
 * @note null
 */
void crc_ll_reset_crc(void) {
#if defined(STM32F40_41xxx) || defined(STM32F10X_HD)
    CRC_ResetDR(); // st 外设库
#elif defined(GD32F407) || defined(GD32F10X_HD)
    crc_data_register_reset(); // gd 外设库
#elif defined(PY32F071xB)
    __HAL_CRC_DR_RESET(&crc_handle);
#endif
}

/**********************************Private Functions*******************************/


/* [] END OF FILE */
